package org.meluk.billboard.jpa.seabattle;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PostLoad;
import javax.persistence.Transient;
import static org.meluk.billboard.game.seaBattle.SBConstants.SB_BOARD_DIMENSION;
import org.meluk.billboard.jpa.Player;

@Entity
public class SBBoard implements Serializable {

    public SBBoard() {
    }

    public SBBoard(Player owner) {
        this.owner = owner;
        for (int i = 0; i < SB_BOARD_DIMENSION; i++) {
            for (int j = 0; j < SB_BOARD_DIMENSION; j++) {
                SBPoint point = new SBPoint(Boolean.TRUE, Boolean.FALSE, j, i);
                pointArray[i][j] = point;
                pointList.add(point);
            }
        }
    }
    private static long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToOne
    @JoinColumn(name = "owner_id")
    private Player owner;
    @Transient
    private SBPoint[][] pointArray = new SBPoint[SB_BOARD_DIMENSION][SB_BOARD_DIMENSION];
    @OneToMany(mappedBy = "board")
    private List<SBPoint> pointList = new ArrayList<SBPoint>(SB_BOARD_DIMENSION * SB_BOARD_DIMENSION);
    @OneToMany(mappedBy = "board")
    private List<Ship> shipList = new ArrayList<Ship>();
    @ManyToOne
    @JoinColumn(name = "game_id")
    private SBGame game;

    @PostLoad
    public void postLoad() {
        for (SBPoint point : pointList) {
            pointArray[point.getY()][point.getX()] = point;
        }
    }

    public void addShip(Ship ship) {
        if (!shipList.contains(ship)) {
            if (ship.getBoard() != null) {
                ship.getBoard().getShipList().remove(ship);
            }
            shipList.add(ship);
            ship.setBoard(this);
        }
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Player getOwner() {
        return owner;
    }

    public void setOwner(Player owner) {
        this.owner = owner;
    }

    public SBPoint[][] getPointArray() {
        return pointArray;
    }

    public List<SBPoint> getPointList() {
        return pointList;
    }

    public List<Ship> getShipList() {
        return shipList;
    }

    public SBGame getGame() {
        return game;
    }

    public void setGame(SBGame game) {
        this.game = game;
    }

    public String printBoard() {
        String killedSymbol = "X";

        String shipSymbol = "1";

        String noShipSymbol = "0";

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < getPointArray().length; i++) {
            for (int j = 0; j < getPointArray()[i].length; j++) {
                SBPoint point = getPointArray()[i][j];
                if (point.getIsAlive() != null && !point.getIsAlive()) {
                    builder.append(killedSymbol);
                } else {
                    if (point.getIsWithShip() != null && point.getIsWithShip()) {
                        builder.append(shipSymbol);
                    } else {
                        builder.append(noShipSymbol);
                    }
                }
                builder.append("\t");
            }
            builder.append("\n");
        }

        return builder.toString();
    }
}